﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace Läxomatic
{
    class Matrix
    {
        private List<Drawable> _elever = new List<Drawable>();
        private List<Drawable> _uppgifter = new List<Drawable>();
        private Tabell<Task> _elevUppgifter = new Tabell<Task>();
        private string _course;
        private Point _p;
        private Size _s;
        private Button[] _btnList;

        //Skapar en lista med drawables för elever
        private List<Drawable> getElevDrawable(string course)
        {
            Tabell<string> ElevTabell = new Tabell<string>(Myskul.Command("SELECT fName, lname, s.id FROM user u JOIN student AS s ON (u.id = s.userId) JOIN user_course AS uc ON (u.Id = uc.userId) JOIN course AS c ON (c.id = uc.courseId) WHERE c.name = '" + course + "'"));
            List<Drawable> temp = new List<Drawable>();
            for (int i = 0; i < ElevTabell.Length(); i++)
                temp.Add(new Drawable(ElevTabell[i, 0] + " " + ElevTabell[i, 1], ElevTabell[i, 2],true));
            return temp;
        }
        //Skapar en lista med drawables för uppgifter
        private List<Drawable> getUppgiftDrawable(string course)
        { 
            List<Drawable> temp = new List<Drawable>();
            Tabell<string> taskResult = new Tabell<string>(Myskul.Command("SELECT t.name, t.id FROM task t JOIN course as c ON (t.courseID = c.Id)  WHERE c.name = '" + course + "'"));
            for (int i = 0; i < taskResult.Length(); i++)
            {
                temp.Add(new Drawable(taskResult[i,0],taskResult[i,1],false));
            }
            return temp;
        }

        private List<int> getId(List<Drawable> DrawableList)
        {
            if (DrawableList == null)
                return null;
            List<int> temp = new List<int>();
            foreach (Drawable x in DrawableList)
            {
                temp.Add(Convert.ToInt32(x.getName()));
            }
            return temp;
        }
        //Skapar en tabell emd tasks, vilket är alla elevers individuella uppgifter.
        private Tabell<Task> getElevUppgifter(List<int> elevId, List<int> taskId)
        {
            if (elevId==null||taskId==null)
            {
                return null;
            }
            Tabell<Task> temp = new Tabell<Task>();
            Tabell<string> au = new Tabell<string>();

            for (int x = 0; x < taskId.Count; x++)
                for (int y = 0; y < elevId.Count; y++)
                {
                    temp[x, y] = new Task();
                }

            Tabell<string> tempTabell = new Tabell<string>(Myskul.Command("SELECT t.courseId FROM task AS t JOIN submit AS su ON (su.taskId = t.id) WHERE su.studentId ='" + elevId[0] + "' AND su.taskId='" + taskId[0] + "';"));
            if (tempTabell.isEmpty())
            {
                return temp;
            }
            string courseId = tempTabell[0, 0];

            if (elevId.Count == 1)
            {
                au = new Tabell<string>(Myskul.Command("SELECT su.taskId,su.studentId,su.gradeStatus,su.submitStatus,su.mandatory,su.id,t.maxpoints FROM user AS u JOIN student AS s ON ( s.userId = u.id) JOIN submit AS su ON (su.studentId = s.id) JOIN task AS t ON (t.id = su.taskID) WHERE t.courseId = '" + courseId + "' AND su.studentId='" + elevId[0] + "';"));
                for (int i = 0; i < au.Length() && !au.isEmpty(); i++)
                {
                    temp[taskId.IndexOf(Convert.ToInt32(au[i, 0])), 0] = new Task(Convert.ToInt32(au[i, 2]), Convert.ToInt32(au[i, 3]), Convert.ToBoolean(au[i, 4]), au[i,5],Convert.ToInt32(au[i,6]));
                }
            }
            else
                if (taskId.Count == 1)
                {
                    au = new Tabell<string>(Myskul.Command("SELECT su.taskId,su.studentId,su.gradeStatus,su.submitStatus,su.mandatory,su.id,t.maxpoints FROM user AS u JOIN student AS s ON ( s.userId = u.id) JOIN submit AS su ON (su.studentId = s.id) JOIN task AS t ON (t.id = su.taskID) WHERE su.taskId='" + taskId[0] + "' AND t.courseId = '" + courseId + "';"));
                    for (int i = 0; i < au.Length() && !au.isEmpty(); i++)
                    {
                        temp[0, elevId.IndexOf(Convert.ToInt32(au[i, 1]))] = new Task(Convert.ToInt32(au[i, 2]), Convert.ToInt32(au[i, 3]), Convert.ToBoolean(au[i, 4]), au[i, 5], Convert.ToInt32(au[i, 6]));
                    }
                }
                else
                {
                    au = new Tabell<string>(Myskul.Command("SELECT su.taskId,su.studentId,su.gradeStatus,su.submitStatus,su.mandatory,su.id,t.maxpoints FROM user AS u JOIN student AS s ON ( s.userId = u.id) JOIN submit AS su ON (su.studentId = s.id) JOIN task AS t ON (t.id = su.taskID) WHERE t.courseId = '" + courseId + "';"));
                    for (int i = 0; i < au.Length() && !au.isEmpty(); i++)
                    {
                        temp[taskId.IndexOf(Convert.ToInt32(au[i, 0])), elevId.IndexOf(Convert.ToInt32(au[i, 1]))] = new Task(Convert.ToInt32(au[i, 2]), Convert.ToInt32(au[i, 3]), Convert.ToBoolean(au[i, 4]), au[i, 5], Convert.ToInt32(au[i, 6]));
                    }
                }

            return temp;
        }
        //Skapar en matris utifrån värden för x,y-position, samt höjd och bredd på elevuppgifterna.
        public Matrix(string course, int dy, int dx, int width, int height)
        {
            _p = new Point(dy, dx);
            _s = new Size(width, height);
            _course = course;

            _elever = getElevDrawable(course);
            _uppgifter = getUppgiftDrawable(course);

            List<int> elevId = getId(_elever);
            List<int> taskId = getId(_uppgifter);
            if(elevId.Count > 0 && taskId.Count > 0)
                _elevUppgifter = getElevUppgifter(elevId,taskId);
            SavedData.matrix = this;
            SavedData.Statuslabel.Text = "";
            _btnList = CreateButtons();
        }
        //Uppdaterar matrisen
        public void Refresh()
        {
            List<int> elevId = getId(_elever);
            List<int> taskId = getId(_uppgifter);
            this._elevUppgifter = getElevUppgifter(elevId, taskId);
            _btnList = CreateButtons();
        }
        //Skapar en sub-matris med bara en kolumn/rad för att visa en specifik elev/uppgift.
        public Matrix(string elevId, string uppgiftId)
        {
            if (elevId != null)
                foreach (Drawable x in SavedData.matrix.getElever())
                {
                    if (x.getName() == elevId)
                        _elever.Add(x);
                }
            else
                _elever = SavedData.matrix.getElever();

            if (uppgiftId != null)
                foreach (Drawable x in SavedData.matrix.getUppgifter())
                {
                    if (x.getName() == uppgiftId)
                        _uppgifter.Add(x);
                }
            else
                _uppgifter = SavedData.matrix.getUppgifter();

            List<int> _elevId = getId(_elever);
            List<int> _taskId = getId(_uppgifter);

            _elevUppgifter = getElevUppgifter(_elevId, _taskId);

            _p = SavedData.matrix.getPoint();
            _s = SavedData.matrix.getSize();
            _btnList = CreateButtons();
        }
        //returnerar matrisens position
        public Point getPoint()
        { return _p; }
        //returnerar elevuppgifternas storlek
        public Size getSize()
        { return _s; }
        //returnerar drawables med elever
        public List<Drawable> getElever()
        {
            return _elever;
        }
        //returnerar drawables med uppgifter
        public List<Drawable> getUppgifter()
        {
            return _uppgifter;
        }
        //returnerar kursens namn
        public string getCourse()
        { return _course; }
        //Skapar knapapr av alla drawables/tasks
        private Button[] CreateButtons()
        {
            Size namnS = new Size(Convert.ToInt32(_s.Width * 1.5), _s.Height);
            List<Button> tempList = new List<Button>();
            Button temp = new Button();
            temp.Size = namnS;
            temp.Location = _p;
            temp.Text = "Reset Matrix";
            temp.Click += new EventHandler(temp_Click);
            tempList.Add(temp);

            for (int namnY = 0; namnY < _elever.Count; namnY++)
                tempList.Add(_elever[namnY].Draw(new Point(_p.X, _p.Y + _s.Height * (namnY + 1)), namnS));
            for (int x = 0; x < _uppgifter.Count; x++)
            {
                tempList.Add(_uppgifter[x].Draw(new Point(Convert.ToInt32(_p.X + _s.Width * (x + 1.5)), _p.Y), _s));
                for (int y = 0; y < _elever.Count; y++)
                    tempList.Add(_elevUppgifter[x, y].Draw(new Point(Convert.ToInt32(_p.X + _s.Width * (x + 1.5)), _p.Y + _s.Height * (y + 1)), _s));
            }
            return tempList.ToArray();

        }
        //Skeppar in knapparna i arrayform
        public Button[] Draw()
        {
            SavedData.Statuslabel.Text = "Ritar Matrisen..";
            SavedData.mainPanel.Controls.Clear();
            SavedData.Statuslabel.Text = "Kurs: " + SavedData.matrix._course;
             return _btnList;

        }
        //Det som händer då man klickar reset matrix (den laddar om)
        public void temp_Click(Object sender, System.EventArgs e)
        {
            Matrix matrix = new Matrix(SavedData.matrix.getCourse(), 0, 0, 50, 50);
            SavedData.mainPanel.Controls.Clear();
            SavedData.mainPanel.Controls.AddRange(matrix.Draw());
            SavedData.mainPanel.Focus();

        }
    }
}
